﻿
using Candy.Model;
using Candy.Web.Data;
using GalaSoft.MvvmLight.Command;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq;

namespace Candy.ViewModel
{
    public class BlastSecondaryBaitsViewModel : CandyViewModelBase
    {
        private ObservableCollection<DatabaseDto> _databses;
        public ObservableCollection<DatabaseDto> Databases
        {
            get
            {
                return _databses;
            }
            set
            {
                _databses = value;
                RaisePropertyChanged("Databases");
                UpdateJobs();
            }
        }


        private ObservableCollection<GeneDto> _genesToBlast;
        public ObservableCollection<GeneDto> GenesToBlast
        {
            get
            {
                return _genesToBlast;
            }
            set
            {
                _genesToBlast = value;
                RaisePropertyChanged("GenesToBlast");
                CreateJobs();
            }
        }

        private void CreateJobs()
        {
            List<BlastJobDefinitionDto> jobs = new List<BlastJobDefinitionDto>();
            foreach (var item in GenesToBlast)
            {
                BlastJobDefinitionDto job = new BlastJobDefinitionDto();
                job.EValCutoff = pValueThreshold;
                job.FamilyName = item.Family.Name;
                job.FamilyId = item.FamilyId;
                job.SecondaryBaitDatabase = SelectedDatabase.LocalDBName;
                job.Task = BlastTask.find_ortholog_genes;
                job.GeneId = item.Id;
                job.GeneName = item.Name;
                jobs.Add(job);
            }
            Jobs = jobs;
        }


        private void UpdateJobs()
        {
            if (_jobs != null)
            {
                foreach (var item in _jobs)
                {
                    item.SecondaryBaitDatabase = _selectedDatabase.LocalDBName;
                    item.EValCutoff = _pValueThreshold;
                }
                RaisePropertyChanged("Jobs");
            }
        }


        private List<BlastJobDefinitionDto> _jobs;
        public List<BlastJobDefinitionDto> Jobs
        {
            get
            {
                return _jobs;
            }
            set
            {
                _jobs = value;
                RaisePropertyChanged("Jobs");
            }
        }


        private DatabaseDto _selectedDatabase;
        public DatabaseDto SelectedDatabase
        {
            get
            {
                return _selectedDatabase;
            }
            set
            {
                _selectedDatabase = value;
                RaisePropertyChanged("SelectedDatabase");
                UpdateJobs();
            }
        }

        private double _pValueThreshold = 0.05;
        public double pValueThreshold
        {
            get
            {
                return _pValueThreshold;
            }
            set
            {
                _pValueThreshold = value;
                RaisePropertyChanged("pValueThreshold");
                UpdateJobs();
            }
        }


        IDataService _dataService;
        public BlastSecondaryBaitsViewModel(IDataService dataService)
        {
            _dataService = dataService;
        }


        private RelayCommand _loadDatabses;
        public RelayCommand LoadDatabases
        {
            get
            {
                return _loadDatabses ?? (_loadDatabses = new RelayCommand(ExecLoadDatabases, CanLoadDatabases));
            }
        }

        /// <summary>
        /// Checks whether the LoadDatabases command is executable
        /// </summary>
        private bool CanLoadDatabases()
        {
            return true;
        }

        /// <summary>
        /// Executes the LoadDatabases command 
        /// </summary>
        private void ExecLoadDatabases()
        {
            Databases = new ObservableCollection<DatabaseDto>(_dataService.Databases.Where(x=>x.IsSecondaryDB).OrderBy(x => x.DisplayName));
            SelectedDatabase = Databases.FirstOrDefault();
        }



    }
}
